﻿using System;
using System.Collections.Generic;
using System.Linq;
using Pixels.Logic;
using Pixels.Logic.GameplayEvents;
using Ur;
namespace Pixels.Logic
{
    public class BasicLogicFlow : ILogicFlow
    {

        public void commenceTurnEnd() {
            END_TURN();
            commenceNextDay();

            Sargon.Audio.play((new[] { "monster", "monster2" }).GetRandom());

        }

        void END_TURN() {

            eventsThisTurn.Clear();

            World.Colony.reset();

            foreach (var structure in World.Colony.allStructures)   structure.executeTurn();
            foreach (var colonist in World.Colony.allColonists)     colonist.executeTurn();

            foreach (var logicRule in logicRules)                   logicRule.execute();

            foreach (var evt in this.eventsThisTurn) {
                Ur.Debug.Log("EVENT EXECUTED : " + evt.getLongDescription()); 
                evt.execute();
            }

            //World.Colony.reset();

            foreach (var child in Interface.Interface.Instance.turnLogWindow.children.ToArray()) {
                if (child is Interface.Label) child.die();
            }

            var x = 90;
            var y = 90;
            foreach (var evt in this.eventsThisTurn) {
                var desc = evt.getLongDescription();
                var l = new Interface.Label(desc, x, y, (int)logWindow.ScreenRect.w - 100, 120);
                y += 60;
                l.attachToParent(logWindow);                
            }           

        }

        Interface.Window logWindow { get { return Interface.Interface.Instance.turnLogWindow;  } }

        List<LogicRule> logicRules = new List<LogicRule>();

        public void addRule(LogicRule rule) { logicRules.Add(rule); }


        internal ISet<GameplayEvent> eventsThisTurn = new HashSet<GameplayEvent>();

        void commenceNextDay() {
            World.startDay();
            Interface.Interface.Instance.turnLogWindow.show();

        }

        void ILogicFlow.injectEvents(IEnumerable<GameplayEvent> events) {
            this.eventsThisTurn.UnionWith(events);
        }
        void ILogicFlow.injectEvent(GameplayEvent evt) {
            this.eventsThisTurn.Add(evt);
        }

        GameplayEvent[] ILogicFlow.currentEvents {
            get { return this.eventsThisTurn.ToArray(); }
        }

        public void unfreezePerson() {
            World.Colony.spawnColonist(Colonist.Occupation.colonist);
        }
    }

    public interface ILogicFlow
    {
        void commenceTurnEnd();
        void addRule(LogicRule rule);
        void injectEvents(IEnumerable<GameplayEvent> events);
        void injectEvent(GameplayEvent evt);

        GameplayEvent[] currentEvents { get; }

        void unfreezePerson();

        
    }

    public abstract class LogicRule
    {
        internal abstract void execute();
    }
}
